/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package BackEnd;

import Dao.MensajePrivadoDao;
import Dao.MensajePrivadoValueObject;
import Dao.OcupacionDao;
import Dao.OcupacionValueObject;
import Dao.PkId;
import Dao.PkUsuarioXUsuario;
import Dao.SesionDao;
import Dao.SesionValueObject;
import Dao.UsuarioDao;
import Dao.UsuarioValueObject;
import Dao.UsuarioXUsuarioDao;
import Dao.UsuarioXUsuarioValueObject;
import BackEnd.Exceptions.*;
import java.sql.Time;
import java.util.ArrayList;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author emmanuel
 */
public class Usuario {

    private long id;
    private String nombre;
    private String apellido;
    private String telefono;
    private String nombreUsuario;
    private String contrasenia;
    private TipoUsuario tipoUsuario;
    private Ocupacion ocupacion;
    private String descripcion;
    private EstadoUsuario estadoUsuario;
    private Provincia provincia;
    private Pais  pais;
    private Date fechaNacimiento;
    private String sexo;
    private String mail;
    private Date fechaAlta;
    private Date fechaBaja;
    private ArrayList<Usuario> amigos;
    private ArrayList<Sesion> sesiones;
    private ArrayList<MensajePrivado> mensajesPrivados;

    public Usuario() {
    }

    /**
     * Constructor con parámetros
     * @param n nombre
     * @param a apellido 
     * @param t telefono
     * @param nu nombre de usuario
     * @param c contrasenia
     * @param tu tipo de Usuario
     * @param o observaciones
     * @param des descripcion
     * @param p provincia
     * @param pa pais
     * @param fn fecha de nacimiento
     * @param s sexo
     * @param m mail
     * @param fa fecha de alta
     */
    public Usuario(String n, String a, String t, String nu, String c, TipoUsuario tu, Ocupacion o, String des, Provincia p, Pais pa, Date fn, String s, String m, Date fa)
    {
        id = 0;
        nombre = n;
        apellido = a;
        telefono = t;
        nombreUsuario = nu;
        contrasenia = c;
        tipoUsuario = tu;
        ocupacion = o;
        descripcion = des;
        estadoUsuario = new EstadoUsuario();//Poner un estado inicial
        estadoUsuario.setEstado(EstadoUsuario.NUEVO);
        provincia = p;
        pais = pa;
        fechaNacimiento = fn;
        sexo = s;
        mail = m;
        fechaAlta = fa;
        amigos = new ArrayList<Usuario>();
        sesiones = new ArrayList<Sesion>();
        mensajesPrivados = new ArrayList<MensajePrivado>();
    }

    public void enviarMensaje(MensajePrivado mp){
        MensajePrivadoDao mpdao = new MensajePrivadoDao();
        MensajePrivadoValueObject mpvo = new MensajePrivadoValueObject();
        mpvo.setIdUsuarioOrigen((int)this.id);
        mpvo.setIdUsuarioDestino((int)mp.getDestinatario().getId());
        mpvo.setMensaje(mp.getMensaje());
        try {
            mpvo = (MensajePrivadoValueObject) mpdao.create(mpvo);
        } catch (CreateRegisterException ex) {
            Logger.getLogger(Usuario.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * @return the nombre
     */
    public String getNombre() {
        return nombre;
    }

    /**
     * @param nombre the nombre to set
     */
    public void setNombre(String nombre) {
        this.nombre = nombre;
    }

    /**
     * @return the apellido
     */
    public String getApellido() {
        return apellido;
    }

    /**
     * @param apellido the apellido to set
     */
    public void setApellido(String apellido) {
        this.apellido = apellido;
    }

    /**
     * @return the telefono
     */
    public String getTelefono() {
        return telefono;
    }

    /**
     * @param telefono the telefono to set
     */
    public void setTelefono(String telefono) {
        this.telefono = telefono;
    }

    /**
     * @return the nombreUsuario
     */
    public String getNombreUsuario() {
        return nombreUsuario;
    }

    /**
     * @param nombreUsuario the nombreUsuario to set
     */
    public void setNombreUsuario(String nombreUsuario) {
        this.nombreUsuario = nombreUsuario;
    }

    /**
     * @return the contrasenia
     */
    public String getContrasenia() {
        return contrasenia;
    }

    /**
     * @param contrasenia the contrasenia to set
     */
    public void setContrasenia(String contrasenia) {
        this.contrasenia = contrasenia;
    }

    /**
     * @return the tipoUsuario
     */
    public TipoUsuario getTipoUsuario() {
        return tipoUsuario;
    }

    /**
     * @param tipoUsuario the tipoUsuario to set
     */
    public void setTipoUsuario(TipoUsuario tipoUsuario) {
        this.tipoUsuario = tipoUsuario;
    }

    /**
     * @return the ocupacion
     */
    public Ocupacion getOcupacion() {
        return ocupacion;
    }

    /**
     * @param ocupacion the ocupacion to set
     */
    public void setOcupacion(Ocupacion ocupacion) {
        this.ocupacion = ocupacion;
    }

    /**
     * @return the descripcion
     */
    public String getDescripcion() {
        return descripcion;
    }

    /**
     * @param descripcion the descripcion to set
     */
    public void setDescripcion(String descripcion) {
        this.descripcion = descripcion;
    }

    /**
     * @return the estadoUsuario
     */
    public EstadoUsuario getEstadoUsuario() {
        return estadoUsuario;
    }

    /**
     * @param estadoUsuario the estadoUsuario to set
     */
    public void setEstadoUsuario(EstadoUsuario estadoUsuario) {
        this.estadoUsuario = estadoUsuario;
    }

    /**
     * @return the provincia
     */
    public Provincia getProvincia() {
        return provincia;
    }

    /**
     * @param provincia the provincia to set
     */
    public void setProvincia(Provincia provincia) {
        this.provincia = provincia;
    }

    /**
     * @return the pais
     */
    public Pais getPais() {
        return pais;
    }

    /**
     * @param pais the pais to set
     */
    public void setPais(Pais pais) {
        this.pais = pais;
    }

    /**
     * @return the fechaNacimiento
     */
    public Date getFechaNacimiento() {
        return fechaNacimiento;
    }

    /**
     * @param fechaNacimiento the fechaNacimiento to set
     */
    public void setFechaNacimiento(Date fechaNacimiento) {
        this.fechaNacimiento = fechaNacimiento;
    }

    /**
     * @return the sexo
     */
    public String getSexo() {
        return sexo;
    }

    /**
     * @param sexo the sexo to set
     */
    public void setSexo(String sexo) {
        this.sexo = sexo;
    }

    /**
     * @return the mail
     */
    public String getMail() {
        return mail;
    }

    /**
     * @param mail the mail to set
     */
    public void setMail(String mail) {
        this.mail = mail;
    }

    /**
     * @return the fechaAlta
     */
    public Date getFechaAlta() {
        return fechaAlta;
    }

    /**
     * @param fechaAlta the fechaAlta to set
     */
    public void setFechaAlta(Date fechaAlta) {
        this.fechaAlta = fechaAlta;
    }

    /**
     * @return the amigos
     */
    public ArrayList<Usuario> getAmigos() {
        return amigos;
    }

    /**
     * @param amigos the amigos to set
     */
    public void setAmigos(ArrayList<Usuario> amigos) {
        this.amigos = amigos;
    }

    /**
     * Permite agregar un amigo a mi lista de amigos
     * @param ami
     */
    public void agregarAmigo(Usuario ami){
        this.amigos.add(ami);
        UsuarioXUsuarioDao uxudao = new UsuarioXUsuarioDao();
        UsuarioXUsuarioValueObject uxuvo = new UsuarioXUsuarioValueObject();
        uxuvo.setIdUsuario((int)this.id);
        uxuvo.setIdUsuarioAmigos((int)ami.getId());
        try {
            uxudao.create(uxuvo);
        } catch (CreateRegisterException ex) {
            Logger.getLogger(Usuario.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public Usuario getAmigo(long id){
        UsuarioXUsuarioDao uxudao = new UsuarioXUsuarioDao();
        UsuarioXUsuarioValueObject []uxuvo;
        try {
            uxuvo = (UsuarioXUsuarioValueObject[]) uxudao.mostrarConsulta("select * from Usuario where id in (select idUsuarioAmigos from UsuarioXUsuario where idUsuario="+this.id+")");
            Usuario amigo = new Usuario();
            amigo.abrir(id);
            return amigo;
        } catch (NotExistRegisterException ex) {
            Logger.getLogger(Usuario.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        }
    }

    /**
     * @return the sesiones
     */
    public ArrayList<Sesion> getSesiones() {
        return sesiones;
    }

    /**
     * @param sesiones the sesiones to set
     */
    public void setSesiones(ArrayList<Sesion> sesiones) {
        this.sesiones = sesiones;
    }

    public boolean cerrarSesion(Sesion sesion){
        this.sesiones.add(sesion);
        SesionDao sdao = new SesionDao();
        SesionValueObject svo = new SesionValueObject();
        svo.setIdUsuario((int)this.id);
        svo.setFechaInicio(sesion.getFechaInicio());
        java.sql.Date tiempo = new java.sql.Date(sesion.getFechaInicio().getTime());
        svo.setHoraInicio((Time) sesion.getFechaFin());
        svo.setFechaFin(sesion.getFechaFin());
        svo.setHoraFin((Time) sesion.getFechaFin());
        svo.setModoSalida(sesion.getModoSalida());
        try {
            sdao.update(svo);
            return true;
        } catch (UpdateRegisterException ex) {
            Logger.getLogger(Usuario.class.getName()).log(Level.SEVERE, null, ex);
            return false;
        }
    }

    public Sesion abrirSesion(){
        Sesion s = new Sesion(new Date(),null,"");
        this.sesiones.add(s);
        return s;
    }

    public ArrayList<MensajePrivado> getMensajesNuevos() {
        throw new UnsupportedOperationException("Not yet implemented");
    }

    public boolean abrir(String nombreUsuario, String contrasenia) {
        UsuarioDao udao = new UsuarioDao();
        UsuarioValueObject []uvo;
        try {
            uvo = (UsuarioValueObject[]) udao.mostrarConsulta("select * from Usuario where nombreUsuario="+nombreUsuario+" and contrasenia="+contrasenia);
            if(uvo.length == 1)
            {
                this.apellido = uvo[0].getApellido();
                this.contrasenia = uvo[0].getContrasenia();
                this.descripcion = uvo[0].getDescripcion();
                this.fechaAlta = uvo[0].getFechaAlta();
                this.fechaNacimiento = uvo[0].getFechaNac();
                this.id = uvo[0].getId();
                this.mail = uvo[0].getMail();
                this.nombre = uvo[0].getNombre();
                this.nombreUsuario = uvo[0].getNombreUsuario();
                this.sexo = uvo[0].getSexo();
                this.telefono = uvo[0].getTelefono();

                OcupacionDao odao = new OcupacionDao();
                PkId pkOcupacion = new PkId(uvo[0].getIdOcupacion());
                OcupacionValueObject ovo = (OcupacionValueObject)odao.traer(pkOcupacion);
                Ocupacion o = new Ocupacion();
                o.setId(ovo.getId());
                o.setNombre(ovo.getNombre());
                this.ocupacion = o;


                UsuarioValueObject friends[] = (UsuarioValueObject[])udao.mostrarConsulta("select * from Usuario where id in (select idUsuarioAmigos from UsuarioXUsuario where idUsuario="+this.id+")");
                Usuario ami = new Usuario();
                for(int i = 0; i <= friends.length; i++){
                    ami.setId((long)friends[i].getId());
                    ami.setNombre(friends[i].getNombre());
                    ami.setApellido(friends[i].getApellido());
                    ami.setNombreUsuario(friends[i].getNombreUsuario());
                    this.amigos.add(ami);
                }
                // NO TRAIGO NOS MENSAJES Y SOLO TRAIGO LA ULTIMA SESION
                SesionDao sdao = new SesionDao();
                SesionValueObject sesions[] = (SesionValueObject[])sdao.mostrarConsulta("SELECT * FROM Sesion S where idUsuario = "+this.id+" group by fechaInicio having max(fechaInicio)");
                Sesion s = new Sesion();
                for(int i = 0; i < sesions.length; i++){
                    s.setId(sesions[i].getId());
                    s.setFechaInicio(sesions[i].getFechaInicio());
                    s.setFechaFin(sesions[i].getFechaFin());
                    s.setModoSalida(sesions[i].getModoSalida());
                    this.sesiones.add(s);
                }
                return true;
            }
            else
                return true;
        } catch (NotExistRegisterException ex) {
            Logger.getLogger(Usuario.class.getName()).log(Level.SEVERE, null, ex);
            return false;
        }
        
    }

    public long grabar() {
        UsuarioDao udao = new UsuarioDao();
        UsuarioValueObject uvo[];
        try {
            uvo = (UsuarioValueObject[]) udao.mostrarConsulta("select * from Usuario where id="+this.id);
            if(uvo.length == 1)
            {
                uvo[0].setApellido(this.apellido);
                uvo[0].setContrasenia(this.contrasenia);
                uvo[0].setDescripcion(this.descripcion);
                uvo[0].setFechaAlta(this.fechaAlta);
                uvo[0].setFechaNac(this.fechaNacimiento);
                uvo[0].setNombre(this.nombre);
                uvo[0].setNombreUsuario(this.nombreUsuario);
                uvo[0].setSexo(this.sexo);
                uvo[0].setTelefono(this.telefono);
                udao.update(uvo[0]);
                return this.id;
            }
            else
            {
                UsuarioValueObject uv = new UsuarioValueObject();
                uv.setApellido(this.apellido);
                uv.setContrasenia(this.contrasenia);
                uv.setDescripcion(this.descripcion);
                uv.setFechaAlta(this.fechaAlta);
                uv.setFechaNac(this.fechaNacimiento);
                uv.setNombre(this.nombre);
                uv.setNombreUsuario(this.nombreUsuario);
                uv.setSexo(this.sexo);
                uv.setTelefono(this.telefono);
                UsuarioValueObject aux = (UsuarioValueObject)udao.create(uv);
                return aux.getId();
            }
        } catch (NotExistRegisterException ex) {
            Logger.getLogger(Usuario.class.getName()).log(Level.SEVERE, null, ex);
            return 0;
        }
        catch(CreateRegisterException ex){
            return 0;
        }
        catch (UpdateRegisterException ex){
            return 0;
        }

    }

    public boolean abrir(long id){
        UsuarioDao udao = new UsuarioDao();
        PkId pkUsuario = new PkId((int)id);
        UsuarioValueObject uvo;
        try {
            uvo = (UsuarioValueObject) udao.traer(pkUsuario);
            if(uvo != null)
            {
                this.apellido = uvo.getApellido();
                this.contrasenia = uvo.getContrasenia();
                this.descripcion = uvo.getDescripcion();
                this.fechaAlta = uvo.getFechaAlta();
                this.fechaNacimiento = uvo.getFechaNac();
                this.id = uvo.getId();
                this.mail = uvo.getMail();
                this.nombre = uvo.getNombre();
                this.nombreUsuario = uvo.getNombreUsuario();
                this.sexo = uvo.getSexo();
                this.telefono = uvo.getTelefono();

                OcupacionDao odao = new OcupacionDao();
                PkId pkOcupacion = new PkId(uvo.getIdOcupacion());
                OcupacionValueObject ovo = (OcupacionValueObject)odao.traer(pkOcupacion);
                Ocupacion o = new Ocupacion();
                o.setId(ovo.getId());
                o.setNombre(ovo.getNombre());
                this.ocupacion = o;


                UsuarioValueObject friends[] = (UsuarioValueObject[])udao.mostrarConsulta("select * from Usuario where id in (select idUsuarioAmigos from UsuarioXUsuario where idUsuario="+this.id+")");
                Usuario ami = new Usuario();
                for(int i = 0; i <= friends.length; i++){
                    ami.setId(friends[i].getId());
                    ami.setNombre(friends[i].getNombre());
                    ami.setApellido(friends[i].getApellido());
                    ami.setNombreUsuario(friends[i].getNombreUsuario());
                    this.amigos.add(ami);
                }
                // NO TRAIGO NOS MENSAJES Y SOLO TRAIGO LA ULTIMA SESION
                SesionDao sdao = new SesionDao();
                SesionValueObject sesions[] = (SesionValueObject[])sdao.mostrarConsulta("SELECT * FROM Sesion S where idUsuario = "+this.id+" group by fechaInicio having max(fechaInicio)");
                Sesion s = new Sesion();
                for(int i = 0; i < sesions.length; i++){
                    s.setId(sesions[i].getIdUsuario());
                    s.setFechaInicio(sesions[i].getFechaInicio());
                    s.setFechaFin(sesions[i].getFechaFin());
                    s.setModoSalida(sesions[i].getModoSalida());
                    this.sesiones.add(s);
                }
                return true;
            }
            else
                return false;
        } catch (NotExistRegisterException ex) {
            Logger.getLogger(Usuario.class.getName()).log(Level.SEVERE, null, ex);
            return false;
        }
        
    }

    /**
     * @return the id
     */
    public long getId() {
        return id;
    }

    /**
     * @param id the id to set
     */
    public void setId(long id) {
        this.id = id;
    }

    public boolean removerAmigo(Usuario ex) {
        this.amigos.remove(ex);
        UsuarioXUsuarioDao uxudao = new UsuarioXUsuarioDao();
        PkUsuarioXUsuario uxupk = new PkUsuarioXUsuario((int)this.id, (int)ex.getId());
        try {
            uxudao.delete(uxupk);
            return true;
        } catch (DeleteRegisterException ex1) {
            Logger.getLogger(Usuario.class.getName()).log(Level.SEVERE, null, ex1);
            return false;
        }
    }

    /**
     * @return the mensajesPrivados
     */
    public ArrayList<MensajePrivado> getMensajesPrivados() {
        MensajePrivadoDao mpdao = new MensajePrivadoDao();
        MensajePrivadoValueObject mpvo[];
        try {
            mpvo = (MensajePrivadoValueObject[]) mpdao.mostrarConsulta("select * from MensajePrivado where idUsuarioOrigen="+this.id);
            MensajePrivado mp = new MensajePrivado();
            UsuarioValueObject uvo = new UsuarioValueObject();
            Usuario u = null;
            for(int i = 0; i<=mpvo.length; i++)
            {
                mp.setId(mpvo[i].getId());
                mp.setRemitente(this);
                UsuarioDao udao = new UsuarioDao();
                PkId upk = new PkId(mpvo[i].getIdUsuarioDestino());
                uvo = (UsuarioValueObject)udao.traer(upk);
                u = new Usuario();
                u.apellido = uvo.getApellido();
                u.contrasenia = uvo.getContrasenia();
                u.descripcion = uvo.getDescripcion();
                u.fechaAlta = uvo.getFechaAlta();
                u.fechaNacimiento = uvo.getFechaNac();
                u.id = uvo.getId();
                u.mail = uvo.getMail();
                u.nombre = uvo.getNombre();
                u.nombreUsuario = uvo.getNombreUsuario();
                u.sexo = uvo.getSexo();
                u.telefono = uvo.getTelefono();
                mp.setDestinatario(u);
                mp.setFechaEnvio(mpvo[i].getFecha());
                mp.setMensaje(mpvo[i].getMensaje());
                this.mensajesPrivados.add(mp);
            }
            return mensajesPrivados;
        } catch (NotExistRegisterException ex) {
            Logger.getLogger(Usuario.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        }

    }

    /**
     * @param mensajesPrivados the mensajesPrivados to set
     */
    public void setMensajesPrivados(ArrayList<MensajePrivado> mensajesPrivados) {
        this.mensajesPrivados = mensajesPrivados;
    }

    public boolean darDeBaja(Date fechaBaja)
    {
        this.fechaBaja = fechaBaja;
        UsuarioDao udao = new UsuarioDao();
        PkId upk = new PkId((int)this.id);
        try {
            udao.delete(upk);
            return true;
        } catch (DeleteRegisterException ex) {
            Logger.getLogger(Usuario.class.getName()).log(Level.SEVERE, null, ex);
            return false;
        }
    }

    public void borrarMensajePrivado(MensajePrivado mp) {
        MensajePrivadoDao mpvo = new MensajePrivadoDao();
        PkId mppk = new PkId((int)mp.getId());
        try {
            mpvo.delete(mppk);
        } catch (DeleteRegisterException ex) {
            Logger.getLogger(Usuario.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public static boolean validarNombreUsuario(String nombreUsuario) {
        UsuarioDao udao = new UsuarioDao();
        UsuarioValueObject []uvo;
        try {
            uvo = (UsuarioValueObject[]) udao.mostrarConsulta("select * from Usuario where nombreUsuario="+nombreUsuario);
            if(uvo.length == 1)
                return true;
            else
                return false;
        } catch (NotExistRegisterException ex) {
            Logger.getLogger(Usuario.class.getName()).log(Level.SEVERE, null, ex);
            return false;
        }

    }

    public static ArrayList<Usuario> getUsuariosRegistrados() {
        ArrayList<Usuario> lista = new ArrayList<Usuario>();
        Usuario u = new Usuario();
        UsuarioDao udao = new UsuarioDao();
        UsuarioValueObject []uvo;
        try {
            uvo = (UsuarioValueObject[]) udao.listarTodos();
            for(int i = 0; i< uvo.length;i++)
            {
                u.setApellido( uvo[i].getApellido());
                u.setNombre(uvo[i].getNombre());
                u.setNombreUsuario(uvo[i].getNombreUsuario());
                u.setId(uvo[i].getId());
                u.setMail(uvo[i].getMail());
                u.setDescripcion(uvo[i].getDescripcion());
                lista.add(u);
            }
            return lista;
        } catch (NotExistRegisterException ex) {
            Logger.getLogger(Usuario.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        }

    }
}
